home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / external / sharelib / simple_c2f.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-08  |  5.2 KB  |  179 lines

  1. /*
  2. **    $Id: simple_c2f.c,v 1.2 1995/08/02 17:01:36 kirk Exp $
  3. **
  4. ** NAME:
  5. **     simple_c2f
  6. **
  7. ** PURPOSE:
  8. **    This C function is used to demonstrate how to pass all IDL
  9. **    simple varable types to a FORTRAN routine via a C wrapper function.
  10. **    The passed variables are squared in the Fortran routine and
  11. **    returned.
  12. **
  13. ** CATEGORY:
  14. **    Dynamic Link
  15. **
  16. ** CALLING SEQUENCE:
  17. **      This function is called in IDL by using the following command
  18. **
  19. **      IDL> result = CALL_EXTERNAL('simple_c2f.so', '_simple_c2f',    $
  20. **      IDL>            byte_var, short_var, long_var, float_var,        $
  21. **      IDL>            double_var, string_var, /S_VALUE )
  22. **
  23. ** INPUTS:
  24. **
  25. **      Byte_var:       A scalar byte variable
  26. **
  27. **      Short_var:      A scalar short integer variable
  28. **
  29. **      Long_var:       A scalar long integer variable
  30. **
  31. **      Float_var:      A scalar float variable
  32. **
  33. **      Double_var:     A scalar float variable
  34. **
  35. **      String_var:     A scalar string value (Actally an IDL STRING struct)
  36. **
  37. ** OUTPUTS:
  38. **    All numeric variables are squared and the "squared" string value
  39. **    is returned as the result of Call external. All this squaring
  40. **    is performed in the Fortran function simple_c2f1.    
  41. **
  42. ** SIDE EFFECTS:
  43. **    None.
  44. **
  45. ** RESTRICTIONS:
  46. **    This example assumes that the values are long (4 bytes) and not
  47. **    short integers. An IDL integer is only 2 bytes long, so the variables
  48. **    should be delcared in IDL at type long.
  49. **
  50. ** EXAMPLE:
  51. **-----------------------------------------------------------------------------
  52. ;; The following are the commands that would be used to call this
  53. ;; routine in IDL.
  54. ;;
  55.         byte_var        = 1b
  56.         short_var       = 2
  57.         long_var        = 3l
  58.         float_var       = 4.0
  59.         double_var      = 5d0
  60.         string_var      = "SIX"
  61.  
  62.         result = CALL_EXTERNAL('simple_c2f.so', '_simple_c2f',     $
  63.                         byte_var, short_var, long_var, float_var,            $
  64.                         double_var, string_var , /S_VALUE)
  65.  
  66. **-----------------------------------------------------------------------------
  67. **
  68. ** MODIFICATION HISTORY:
  69. **    Written October, 1993        KDB
  70. **    
  71. ** Declare Header files
  72. */
  73. #include <stdio.h>
  74.  
  75. /*
  76. ** Declare the structure for an IDL string (From IDL User's Guide).
  77. */
  78. typedef struct {
  79.    unsigned short slen;         /* length of the string         */
  80.    short stype;                 /* Type of string               */
  81.    char *s;                     /* Pointer to chararcter array  */
  82. } STRING;
  83.  
  84. /*
  85. ** Define a C macro that will return the length of an IDL String
  86. */
  87.  
  88. #define STR_LEN(__str)    ((long)(__str)->slen)
  89.  
  90. /*
  91. ** Declare the function
  92. */
  93.  
  94. char *
  95. simple_c2f(argc, argv)
  96. int argc;
  97. void *argv[];
  98. {
  99. /*
  100. ** Since this function is used on different UNIX platforms the fortran
  101. ** entry points can differ. Some systems (SUN) fortran compliers will
  102. ** add and extra '_' to the end of the routine. To correct for this
  103. ** add some preprocessor commmands. 
  104. */
  105.   
  106. #if defined(SPARC) || defined(OSF1)
  107.    void simple_c2f1_();
  108. #else
  109.    void simple_c2f1();  /* function prototype for the fortran funct */
  110. #endif
  111.  
  112. /*
  113. ** Declare variables
  114. */
  115.    char         *byte_var;      /* Pointer to a char ( One byte )       */
  116.    short        *short_var;     /* Pointer to short integer             */
  117.    long         *long_var;      /* Pointer to long                      */
  118.    float        *float_var;     /* Pointer to float                     */
  119.    double       *double_var;    /* Pointer to double                    */
  120.    STRING       *string_var;    /* Pointer to IDL string structure      */
  121.    char        *return_string; /* Pointer to the returned string    */
  122.    long        ch_size = 100;  /* size of the return string         */
  123.  
  124. /*
  125. ** Insure that the correct number of arguments were passed in (argc = 6)
  126. */
  127.  
  128.    if(argc != 6)
  129.    {
  130.    /*
  131.    ** Print an error message and return
  132.    */
  133.       fprintf(stderr,"simple_c2f: Incorrect number of arguments\n");
  134.       return((char*)NULL);  /* Signal an error */
  135.    }
  136. /*
  137. ** Cast the pointer in argv to the pointer variables
  138. */
  139.    byte_var     = (char *)   argv[0];
  140.    short_var    = (short *)  argv[1];
  141.    long_var     = (long *)   argv[2];
  142.    float_var    = (float *)  argv[3];
  143.    double_var   = (double *) argv[4];
  144.    string_var   = (STRING *) argv[5];
  145.  
  146. /*
  147. ** Now malloc some space for the return string.
  148. */
  149.    if( (return_string=(char*)malloc((unsigned)ch_size+1))
  150.        == (char*)NULL)
  151.    {
  152.       fprintf(stderr,"simple_c2f: malloc error \n");
  153.       return(return_string);
  154.    }
  155.  
  156. /*
  157. ** Now we need to call the fortran subroutine. The FORTRAN subroutine 
  158. ** uses varable length strings for the string parameter( CHARACTER*(*) ).
  159. ** Because of this we must pass in the length of each string that is 
  160. ** passed to the FORTRAN subprocedure. The string lengths are added 
  161. ** to the end of the parameter list. 
  162. */
  163.  
  164. #if defined(SPARC) || defined(OSF1)
  165.    simple_c2f1_(byte_var, short_var, long_var, float_var, double_var, 
  166.      string_var->s, return_string, &ch_size, STR_LEN(string_var),ch_size );
  167. #else
  168.    simple_c2f1(byte_var, short_var, long_var, float_var, double_var,
  169.          string_var->s, return_string, &ch_size, STR_LEN(string_var),ch_size );
  170. #endif
  171.  
  172. /*
  173. ** That should be it, return the new string to the calling routine
  174. */
  175.    return((char*)return_string);
  176.  
  177.  
  178.